const path = require("path"); //引入path模块
// const HardSourceWebpackPlugin = require("hard-source-webpack-plugin"); 缓存加速二次构建速度
const LodashModuleReplacementPlugin = require("lodash-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); // 去掉注释
const IS_DEV = process.env.NODE_ENV === "development"; //是否开发环境
const CompressionWebpackPlugin = require("compression-webpack-plugin"); // gzip压缩
function resolve(dir) {
  return path.join(__dirname, dir); //path.join(__dirname)设置绝对路径
}
const devNeedCdn = false; // 本地环境是否需要使用cdn
const { HashedModuleIdsPlugin } = require("webpack"); //只打包改变的文件
const cdn = {
  // cdn：模块名称和模块作用域命名（对应window里面挂载的变量名称）
  externals: {
    vue: "Vue",
    vuex: "Vuex",
    "vue-router": "VueRouter",
    marked: "marked",
    "highlight.js": "hljs",
    nprogress: "NProgress",
    axios: "axios",
  },
  // cdn的css链接
  css: ["https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css"],
  // cdn的js链接
  js: [
    "https://cdn.bootcss.com/vue/2.6.10/vue.min.js",
    "https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js",
    "https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js",
    "https://cdn.bootcss.com/marked/0.8.0/marked.min.js",
    "https://cdn.bootcss.com/highlight.js/9.18.1/highlight.min.js",
    "https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js",
    "https://cdn.bootcss.com/axios/0.19.2/axios.min.js",
  ],
};

module.exports = {
  lintOnSave: false, // 是否开启编译时是否不符合eslint提示
  productionSourceMap: false,
  assetsDir: "static", // 静态文件目录
  publicPath: "./", // 编译后的地址，可以根据环境进行设置
  devServer: {
    open: false, // 自动启动浏览器
    // host: "0.0.0.0", // localhost
    // port: 8080, // 端口号
    https: false,
    // hotOnly: false, // 热更新
    proxy: {
      "^/sso": {
        target: "/sso", // 重写路径
        ws: true, //开启WebSocket
        secure: false, // 如果是https接口，需要配置这个参数
        changeOrigin: true,
      },
    },
  },
  // configureWebpack() {
  //   const devPlugins = [
  //     /**
  //      * 缓存加速二次构建速度
  //      */
  //     new HardSourceWebpackPlugin(),
  //     new HardSourceWebpackPlugin.ExcludeModulePlugin([
  //       {
  //         test: /mini-css-extract-plugin[\\/]dist[\\/]loader/,
  //       },
  //     ]),
  //   ];
  //   if (IS_DEV) {
  //     return {
  //       plugins: devPlugins,
  //     };
  //   }
  // },

  chainWebpack: (config) => {
    // ============预先加载模块 关闭============
    //   config.plugins.delete('prefetch')

    // webpack 会默认给commonChunk打进chunk-vendors，所以需要对webpack的配置进行delete
    config.optimization.delete("splitChunks");
    // ============注入cdn start============
    config.plugin("html").tap((args) => {
      // 生产环境或本地需要cdn时，才注入cdn
      if (!IS_DEV || devNeedCdn) args[0].cdn = cdn;
      return args;
    });
    // ============注入cdn start============
    //压缩图片
    config.module
      .rule("images")
      .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
      .use("image-webpack-loader")
      .loader("image-webpack-loader")
      .options({
        bypassOnDebug: true,
      })
      .end();

    // 配置别名
    config.resolve.alias
      .set("@", resolve("src"))
      .set("assets", resolve("src/assets"))
      .set("components", resolve("src/components"))
      .set("router", resolve("src/router"))
      .set("utils", resolve("src/utils"))
      .set("store", resolve("src/store"))
      .set("views", resolve("src/views"));
  },
  configureWebpack: (config) => {
    // 用cdn方式引入，则构建时要忽略相关资源
    if (!IS_DEV || devNeedCdn) config.externals = cdn.externals;
    // 生产环境相关配置
    if (!IS_DEV) {
      config.plugins.push(
        // new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/),
        new LodashModuleReplacementPlugin()
      );
      config.plugins.push(
        new UglifyJsPlugin({
          uglifyOptions: {
            output: {
              comments: false, // 去掉注释
            },
            //生产环境自动删除console
            compress: {
              drop_debugger: true,
              drop_console: true,
              pure_funcs: ["console.log"], //移除console
            },
          },
          sourceMap: false,
          parallel: true,
        })
      );

      //gzip压缩
      const productionGzipExtensions = ["html", "js", "css"];
      config.plugins.push(
        new CompressionWebpackPlugin({
          filename: "[path].gz[query]",
          algorithm: "gzip",
          test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
          threshold: 10240, // 只有大小大于该值的资源会被处理 10240
          minRatio: 0.8, // 只有压缩率小于这个值的资源才会被处理
          deleteOriginalAssets: false, // 删除原文件
        })
      ),
        // 用于根据模块的相对路径生成 hash 作为模块 id, 一般用于生产环境
        config.plugins.push(new HashedModuleIdsPlugin());
      // 公共代码抽离
      config.optimization = {
        splitChunks: {
          cacheGroups: {
            vendor: {
              chunks: "all",
              test: /node_modules/,
              name: "vendor",
              minChunks: 1,
              maxInitialRequests: 5,
              minSize: 0,
              priority: 100,
            },
            common: {
              chunks: "all",
              test: /[\\/]src[\\/]js[\\/]/,
              name: "common",
              minChunks: 2,
              maxInitialRequests: 5,
              minSize: 0,
              priority: 60,
            },
            styles: {
              name: "styles",
              test: /\.(sa|sc|c)ss$/,
              chunks: "all",
              enforce: true,
            },
            runtimeChunk: {
              name: "manifest",
            },
          },
        },
      };

      // 取消webpack警告的性能提示
      config.performance = {
        hints: "warning",
        //入口起点的最大体积
        maxEntrypointSize: 1000 * 500,
        //生成文件的最大体积
        maxAssetSize: 1000 * 1000,
        //只给出 js 文件的性能提示
        assetFilter: function (assetFilename) {
          return assetFilename.endsWith(".js");
        },
      };
    }
  },
  css: {
    extract: true, //提取css代码
    loaderOptions: {
      sass: {
        prependData: `
               @import "@/assets/scss/variable.scss"; 
               @import "@/assets/scss/common.scss";
               @import "@/assets/scss/mixin.scss";
              `,
      },
    },
  },
};
